﻿using System;
using System.Data;
using System.Linq;
using System.Collections.Generic;
using ORM;

namespace Concret
{
/// <summary>
/// 照片
/// </summary>
public class Photo : DataObject
{
public Photo(DbOperation dbOperation) => base.dbOp = dbOperation;

	/// <summary>
	/// 数据表
	/// </summary>
	public override string TABLE_NAME => "photo";
	/// <summary>
	/// 数据表对Sql适配
	/// </summary>
	public string SQL_TABLE => dbOp.DBCode(TABLE_NAME);
	/// <summary>
	/// 数据表注释
	/// </summary>
	public override string TABLE_COMMENT => "照片";
	
	#region 字段
#region 目录
/// <summary>
/// “目录”在数据库的字段名
/// </summary>
public const string FIELD_DIR = "dir", DESCR_DIR = "目录";
/// <summary>
/// “dir”对Sql适配
/// </summary>
public string SQL_DIR => dbOp.DBCode(FIELD_DIR);
/// <summary>
/// “目录”在类中的属性名
/// </summary>
public const string VAR_DIR = "Dir_Val";
long? dir_id;
/// <summary>
/// “目录”值
/// </summary>
public Dir Dir_Val
{
	get
	{
		if(dir_id.HasValue && (dir_val==null || dir_val.Id!=dir_id.Value))
		{
			dir_val = dbOp.Dir.GetById(dir_id.Value);
			if(dir_val==null) dir_id=null;
		}
		return dir_val;
	}
	set
	{
		if(value?.Id!=dir_id) ChangedFVs[FIELD_DIR] = value?.Id;

		dir_val = value;
		dir_id = value?.Id;
		FVs[FIELD_DIR] = value?.Id;
	}
}
Dir dir_val;
#endregion

#region 路径
/// <summary>
/// “路径”在数据库的字段名
/// </summary>
public const string FIELD_PATH = "path", DESCR_PATH = "路径";
/// <summary>
/// “path”对Sql适配
/// </summary>
public string SQL_PATH => dbOp.DBCode(FIELD_PATH);
/// <summary>
/// “路径”在类中的属性名
/// </summary>
public const string VAR_PATH = "Path_Val";
string path_val;
/// <summary>
/// “路径”值
/// </summary>
public string Path_Val {get => path_val; set {FVs[FIELD_PATH]=value; if(value!=path_val) ChangedFVs[FIELD_PATH]=path_val=value;}}
#endregion

#region 备注
/// <summary>
/// “备注”在数据库的字段名
/// </summary>
public const string FIELD_REMARK = "remark", DESCR_REMARK = "备注";
/// <summary>
/// “remark”对Sql适配
/// </summary>
public string SQL_REMARK => dbOp.DBCode(FIELD_REMARK);
/// <summary>
/// “备注”在类中的属性名
/// </summary>
public const string VAR_REMARK = "Remark_Val";
string remark_val;
/// <summary>
/// “备注”值
/// </summary>
public string Remark_Val {get => remark_val; set {FVs[FIELD_REMARK]=value; if(value!=remark_val) ChangedFVs[FIELD_REMARK]=remark_val=value;}}
#endregion

#region 标题
/// <summary>
/// “标题”在数据库的字段名
/// </summary>
public const string FIELD_TITLE = "title", DESCR_TITLE = "标题";
/// <summary>
/// “title”对Sql适配
/// </summary>
public string SQL_TITLE => dbOp.DBCode(FIELD_TITLE);
/// <summary>
/// “标题”在类中的属性名
/// </summary>
public const string VAR_TITLE = "Title_Val";
string title_val;
/// <summary>
/// “标题”值
/// </summary>
public string Title_Val {get => title_val; set {FVs[FIELD_TITLE]=value; if(value!=title_val) ChangedFVs[FIELD_TITLE]=title_val=value;}}
#endregion

#region 更新标志，用于更新图片后再浏览时刷新缓存
/// <summary>
/// “更新标志，用于更新图片后再浏览时刷新缓存”在数据库的字段名
/// </summary>
public const string FIELD_UPDATED = "updated", DESCR_UPDATED = "更新标志，用于更新图片后再浏览时刷新缓存";
/// <summary>
/// “updated”对Sql适配
/// </summary>
public string SQL_UPDATED => dbOp.DBCode(FIELD_UPDATED);
/// <summary>
/// “更新标志，用于更新图片后再浏览时刷新缓存”在类中的属性名
/// </summary>
public const string VAR_UPDATED = "Updated_Val";
long? updated_val;
/// <summary>
/// “更新标志，用于更新图片后再浏览时刷新缓存”值
/// </summary>
public long? Updated_Val {get => updated_val; set {FVs[FIELD_UPDATED]=value; if(value!=updated_val) ChangedFVs[FIELD_UPDATED]=updated_val=value;}}
#endregion

#region 用户
/// <summary>
/// “用户”在数据库的字段名
/// </summary>
public const string FIELD_USER = "user", DESCR_USER = "用户";
/// <summary>
/// “user”对Sql适配
/// </summary>
public string SQL_USER => dbOp.DBCode(FIELD_USER);
/// <summary>
/// “用户”在类中的属性名
/// </summary>
public const string VAR_USER = "User_Val";
long? user_id;
/// <summary>
/// “用户”值
/// </summary>
public Users User_Val
{
	get
	{
		if(user_id.HasValue && (user_val==null || user_val.Id!=user_id.Value))
		{
			user_val = dbOp.Users.GetById(user_id.Value);
			if(user_val==null) user_id=null;
		}
		return user_val;
	}
	set
	{
		if(value?.Id!=user_id) ChangedFVs[FIELD_USER] = value?.Id;

		user_val = value;
		user_id = value?.Id;
		FVs[FIELD_USER] = value?.Id;
	}
}
Users user_val;
#endregion

#endregion

		#region 单表查询
		/// <summary>
		/// 根据this已填充或刷新的属性来查询数据(使用参数查询机制)。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则从结果中用linq Where过滤或选择GetBySqlWhere
		/// </summary>
		/// <param name="and_or">and/or</param>
		/// <param name="maxCount">结果最多记录数(默认无限制)</param>
		/// <param name="orders">结果排序设置</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> GetByFVs(string and_or = "and", int maxCount = 0, params (string field, string order)[] orders)
		=> base.GetByFVs(and_or, maxCount, orders).Cast<Photo>();

		/// <summary>
		/// 查询(不使用参数查询机制)
		/// </summary>
		/// <param name="sqlWhere">查询条件where子句</param>
		/// <param name="maxCount">结果最多记录数(默认无限制)</param>
		/// <param name="orders">结果排序设置</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> GetBySqlWhere(string sqlWhere = null, int maxCount = 0, params (string field, string order)[] orders)
		=> base.GetBySqlWhere(sqlWhere, maxCount, orders).Cast<Photo>();

		/// <summary>
		/// 查询(使用参数查询机制)
		/// </summary>
		/// <param name="conditions">查询条件。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则从结果中用linq Where过滤或选择GetBySqlWhere</param>
		/// <param name="and_or">and/or</param>
		/// <param name="maxCount">结果最多记录数(默认无限制)</param>
		/// <param name="orders">结果排序设置</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> GetByParameter(IEnumerable<(string field, string op, object value)> conditions = null, string and_or = "and", int maxCount = 0, params (string field, string order)[] orders)
		=> base.GetByParameter(conditions, and_or, maxCount, orders).Cast<Photo>();

		/// <summary>
		/// 查询(使用参数查询机制，与重载的GetByParameter一致)
		/// </summary>
		/// <param name="fieldVals">查询条件。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则从结果中用linq Where过滤或选择GetBySqlWhere</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> GetByParameter(params (string field, string op, object value)[] fieldVals)
		=> base.GetByParameter(conditions: fieldVals).Cast<Photo>();

		/// <summary>
		/// 根据Id来获取记录
		/// </summary>
		/// <param name="Id">id值</param>
		/// <returns>存在返回对应那条记录，否则为null</returns>
		public new Photo GetById(long Id)
		=> base.GetById(Id) as Photo;
		#endregion

		#region 获取分页记录
		/// <summary>
		/// 根据this已填充或刷新的属性来获取分页数据(使用参数查询机制)。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则选择PageBySqlWhere
		/// </summary>
		/// <param name="indexBasedOne">页码(首页为1)</param>
		/// <param name="perPage">每页记录数</param>
		/// <param name="and_or">and/or</param>
		/// <param name="orders">排序设置(默认id降序)</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> PageByFVs(int indexBasedOne = 1, int perPage = 10, string and_or = "and", params (string field, string order)[] orders)
		=> base.PageByFVs(indexBasedOne, perPage, and_or, orders).Cast<Photo>();

		/// <summary>
		/// 分页(不使用参数查询机制)
		/// </summary>
		/// <param name="indexBasedOne">页码(首页为1)</param>
		/// <param name="perPage">每页记录数</param>
		/// <param name="sqlWhere">查询条件where子句</param>
		/// <param name="orders">排序设置(默认id降序)</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> PageBySqlWhere(int indexBasedOne = 1, int perPage = 10, string sqlWhere = null, params (string field, string order)[] orders)
		=> base.PageBySqlWhere(indexBasedOne, perPage, sqlWhere, orders).Cast<Photo>();

		/// <summary>
		/// 分页(使用参数查询机制)
		/// </summary>
		/// <param name="indexBasedOne">页码(首页为1)</param>
		/// <param name="perPage">每页记录数</param>
		/// <param name="conditions">查询条件。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则选择PageBySqlWhere</param>
		/// <param name="and_or"></param>
		/// <param name="orders">排序设置(默认id降序)</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> PageByParameter(int indexBasedOne = 1, int perPage = 10, IEnumerable<(string field, string op, object value)> conditions = null, string and_or = "and", params (string field, string order)[] orders)
		=> base.PageByParameter(indexBasedOne, perPage, conditions, and_or, orders).Cast<Photo>();

		/// <summary>
		/// 分页(使用参数查询机制，与重载的PageByParameter一致)
		/// </summary>
		/// <param name="fieldVals">查询条件。为了简化设计与兼顾灵活性，所有条件关系为单层单连接，如果要混合组合和优先级，则选择PageBySqlWhere</param>
		/// <returns>对象集合</returns>
		public new IEnumerable<Photo> PageByParameter(params (string field, string op, object value)[] fieldVals)
		=> base.PageByParameter(conditions: fieldVals).Cast<Photo>();
		#endregion
}
}